#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,2002 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)85   1.17   src/csm/core/cmds/mgmtsvr.perl, csmcore, csm_rpyxh, rpyxht1f3 8/28/02 11:22:02

use strict;
use locale;
BEGIN
  {
	# this enables us to redirect where it looks for other CSM files during development
	$::csmroot = $ENV{'CSM_ROOT'} ? $ENV{'CSM_ROOT'} : '/opt/csm';
	$::csmpm = "$::csmroot/pm";
	$::csmbin = "$::csmroot/bin";
  }
use lib $::csmpm;
use Getopt::Std;
require NodeUtils;

# For the usage, see nodecmds.msg
sub usage { NodeUtils->message('I', 'IMsgMgmtsvrUsage');  exit (scalar(@_) ? $_[0] : 1); }

$::MSGCAT = 'nodecmds.cat';
$::MSGMAPPATH = "$::csmroot/msgmaps";

# Parse the cmd line args and check them
if (! getopts('n:NhvVdk') ) { &usage; }
if ($::opt_h) { &usage(0); }
if (scalar(@ARGV) > 1) { &usage; }
if (scalar(@ARGV) > 0 && ($::opt_d||$::opt_N)) { &usage; }
if (scalar(@ARGV) == 0 && defined($::opt_n)) { &usage; }

$::VERBOSE = $::opt_v || $::opt_V ;
$ENV{'CT_MANAGEMENT_SCOPE'} = 1;      # set local scope because we only want the local Management Server class
delete $ENV{'CT_CONTACT'};

if (scalar(@ARGV) > 0)     # they are setting the mgmt svr
  {
	# Should we do this or not?  If this name came from the mgmt svr, it might be better to use it
	# exactly.  If it came from the cmd line on the node, we should try name resolution.
	my $ms = NodeUtils->tryHost(shift @ARGV);
	#my $ms = shift @ARGV;
	#print "opt_n=$::opt_n\n";
	&setMgmtSvr($ms, $::opt_n);
  }
elsif ($::opt_d)      # they are removing the mgmt svr
  {
	&rmMgmtSvr();
  }
else       # displaying the mgmt svr
  {
	# These are the various cases:
	# - only a node, mgmt svr set - rc=0, display: foo.com
	# - only a node, mgmt svr not set - rc=11, display: This node does not currently have....
	# - mgmt svr/node, mgmt svr set to self - rc=21, display: foo.com (This node is the mgmt svr for itself.)
	# - mgmt svr/node, mgmt svr set to other mgmt svr - rc=22, display: foo.com (This node is also a mgmt svr for other nodes.)
	# - mgmt svr/node, mgmt svr not set - rc=23, display: This machine is a CSM mgmt svr and a node, but the node does not currently...
	# - only a mgmt svr - rc=31, display: This machine is a CSM management server.
	# - neither a mgmt svr or a node - rc=101, display: This machine is neither a CSM mgmt svr or node.
	if (NodeUtils->isNode())
	  {
		my ($ms, $lhn) = &getMgmtSvr();
		if ($::opt_N) { NodeUtils->message('O','IMsgMS_AND_LHN', $ms, $lhn); }
		elsif (!NodeUtils->isMgmtSvr())
		  {
			if (length($ms)) { print "$ms\n"; }
			else { NodeUtils->message('I11','IMsgNOT_SET'); }
		  }
		else         # also a mgmt svr
		  {
			if (length($ms))
			  {
				if (&isOwnMgmtSvr($ms, $lhn)) { NodeUtils->message('I21','IMsgBOTH_ITSELF', $ms); }
				else { NodeUtils->message('I22','IMsgBOTH_OTHER', $ms); }
			  }
			else { NodeUtils->message('I23','IMsgBOTH_NOT_SET'); }
		  }
	  }
	elsif (NodeUtils->isMgmtSvr())   # only a mgmt svr
	  { NodeUtils->message('I31','IMsgMGMT_SVR'); }
	else       # neither a node or mgmt svr (must only have csm.core installed)
	  { NodeUtils->message('E101','EMsgNEITHER'); }
  }


exit;


# Return true if this machine is the mgmt svr for itself.
sub isOwnMgmtSvr
  {
	my ($ms, $lhn) = @_;

	# If this is a mgmt svr for itself then we should be able to look up the $lhn in the ManagedNode
	# class and the ManagementServer attribute should match $ms.
	my $outref = NodeUtils->runrmccmd('lsrsrc-api', "-i -D ':|:'", qq(-s IBM.ManagedNode::"Hostname='$lhn'"::ManagementServer));
	if (scalar(@$outref) == 0) { return 0; }
	return $$outref[0] eq $ms;
  }


# Return the mgmt svr and local hostname from the IBM.ManagementServer resource class.
# This function assumes we are on a node.
sub getMgmtSvr
  {
	#my ($class, $force) = @_;
	my $outref = NodeUtils->runrmccmd('lsrsrc-api', "-i -D ':|:'", qq(-s IBM.ManagementServer::"ManagerType='CSM'"::Hostname::LocalHostname));
	if (scalar(@$outref) == 0) { return; }
	my ($ms, $lhn) = split(/:\|:/, $$outref[0]);
	return ($ms, $lhn);
  }


sub setMgmtSvr
  {
	my ($ms, $lhn) = @_;

	if (!NodeUtils->isNode()) { NodeUtils->message('E41','EMsgNOT_A_NODE'); }
	
	my $cmd;
	my $changedHostname = 1;     # used to know if we need to refresh at the end
	# See if there is already an entry - if so, replace it
	my ($prevms, $prevlhn) = &getMgmtSvr();
	
	if (length($prevms))		# change the entry
	  {
		if ($ms ne $prevms)   # the Hostname has changed
		  {
			# Undefine the resource and recreate it.  This is necessary to get the DMSRM to go
			# through the full processing in the case that this is really a new mgmt svr.  In the
			# case in which this is the same mgmt svr with a name change, this will also be ok.
			NodeUtils->runrmccmd('rmrsrc-api', '', qq(-s IBM.ManagementServer::"Hostname='$prevms'"));
			my $attr2 = length($lhn) ? qq(::LocalHostname::"$lhn") : '';
			NodeUtils->runrmccmd('mkrsrc-api', '', qq(IBM.ManagementServer::Hostname::"$ms"::ManagerType::"CSM"$attr2));
		  }
		elsif (length($lhn) && $lhn ne $prevlhn)   # Hostname did not change, but LocalHostname did
		  {
			# Note: we don't need to process the -k option in this case because the
			#       ManagementServer resource class will exchange keys if either attribute
			#       changed.
			
			NodeUtils->runrmccmd('chrsrc-api', '', qq(-s IBM.ManagementServer::"Hostname='$prevms'"::LocalHostname::"$lhn"));
			#my $opflag = '0';
			#NodeUtils->runrmccmd('runact', '', qq(-c IBM.ManagementServer RefreshNodeInfo MgmtSvrHostname=$ms OperationFlag=$opflag));
			#todo: handle the no resources found error in case the resource was deleted after we checked it above.
		  }
		elsif($::opt_k)         # no need to change the resource but need to run the refresh action
		  {
			$changedHostname = 0;
			my $opflag = '0';
			#NodeUtils->runrmccmd('runact', '', qq(-c IBM.ManagementServer RefreshNodeInfo MgmtSvrHostname=$ms OperationFlag=$opflag));
			NodeUtils->runrmccmd('runact-api', '', qq(-c IBM.ManagementServer::::RefreshNodeInfo::MgmtSvrHostname::"$ms"::OperationFlag::"$opflag"));
		  }
	  }
	else						# create the entry
	  {
		my $attr2 = length($lhn) ? qq(::LocalHostname::"$lhn") : '';
		NodeUtils->runrmccmd('mkrsrc-api', '', qq(IBM.ManagementServer::Hostname::"$ms"::ManagerType::"CSM"$attr2));
	  }
	
	# Refresh the rmc daemon so it picks up the acl file that was possibly modified as a
	# result of changing the management server
	if ($changedHostname) { NodeUtils->runrmccmd('refresh', '-s ctrmc'); }
  }


sub rmMgmtSvr
  {
	if (!NodeUtils->isNode()) { NodeUtils->message('E41','EMsgNOT_A_NODE'); }
	my ($ms, $lhn) = &getMgmtSvr();
	if (!length($ms)) { return; }     # already gone
	NodeUtils->runrmccmd('rmrsrc-api', '-i', qq(-s IBM.ManagementServer::"Hostname='$ms'"));
  }


# This is not currently used
#sub checkMgmtSvr
#  {
#	my ($class, $force) = @_;
#	my $ms = NodeUtils->getMgmtSvr($force);
#	if (length($ms))       # we are on a node
#	  {
#		# Set the environment var so RMC will connect remotely
#		NodeUtils->msg($msgs, 'V', 'CONNECTING_REMOTELY', $ms);
#		$ENV{'CT_CONTACT'} = $ms;
#	  }
#  }
